package com.atguigu.srb.sms.listener;

import com.atguigu.srb.sms.service.SmsService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

@Component
public class MqListener {
    @Resource
    SmsService smsService;
    //监听发送短信消息
    //1、监听已存在的队列
//    @RabbitListener(queues = {}) //如果 已经通过@Bean注解的方式创建了队列交换机 并绑定 可以直接使用队列名称进行监听
    //2、监听不存在的队列
    @RabbitListener(bindings = {
            //创建绑定对象
            @QueueBinding(
                    //要绑定的队列
                    value = @Queue(value="queue.srb.account",durable = "true"),
                    //要绑定的交换机
                    //因为此处创建了和service-core @Bean一样名称的交换机 所以所有的配置必须保持一致
                    exchange = @Exchange(value = "exchange.srb" , durable = "false",
                            type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "true"),
                    //队列绑定交换机的路由key
                    key = "srb.account.#"
            )
    })
    //参数1：消息对象  参数2：获取到的消息内容  参数3：通道 确认消息时使用
    public void sendAccountMsgListener(Message message , Map<String,String> map , Channel channel) throws IOException {
        try {
            //业务代码
/*
 message.put("mobile", userInfo.getMobile());
        message.put("type","1");//充值=1
        message.put("amount",transAmount.toString());
 */
            String mobile = map.get("mobile");
            String type = map.get("type");
            String amount = map.get("amount");
            String token = map.get("token");//缓存到redis set中
//            if(){//如果redis set  exists中包含token 表示重复消费
//
//            }
            smsService.sendMsg(mobile,Integer.parseInt(type));
            //手动ack：确认消息消费
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                //如果消息重复消费仍然失败 丢弃消息(如果消息队列绑定了死信队列 会丢弃到死信队列中)
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else{
                //让消息重新归队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }

    }

}
